<?php

declare(strict_types=1);

namespace AdminBundle\Auth;

use AdminBundle\Ego\GenericUser;
use AdminBundle\Events\UserLoginEvent;
use AdminBundle\Services\AdminService;
use App\Constants\ErrorCode;
use App\Exception\BusinessException;
use HyperfExt\Auth\Contracts\AuthenticatableInterface;
use HyperfExt\Auth\Contracts\UserProviderInterface;
use Psr\EventDispatcher\EventDispatcherInterface;

class AdminProvider implements UserProviderInterface
{
    /**
     * Retrieve a user by their unique identifier.
     *
     * @param mixed $identifier
     */
    public function retrieveById($identifier): ?AuthenticatableInterface
    {
        $adminService = new AdminService();
        $accountInfo = $adminService->find($identifier);
        return new GenericUser($accountInfo);
    }

    /**
     * Retrieve a user by the given credentials.
     */
    public function retrieveByCredentials(array $credentials): ?AuthenticatableInterface
    {
        $adminService = new AdminService();
        $user = $adminService->findOneBy([
            'account' => $credentials['account'],
        ], ['id', 'username', 'password', 'status']);

        return new GenericUser($user);
    }

    /**
     * Retrieve a user by their unique identifier and "remember me" token.
     *
     * @param mixed $identifier
     */
    public function retrieveByToken($identifier, string $token): ?AuthenticatableInterface
    {
        return null;
    }

    /**
     * Update the "remember me" token for the given user in storage.
     */
    public function updateRememberToken(AuthenticatableInterface $user, string $token): void
    {
    }

    /**
     * Validate a user against the given credentials.
     */
    public function validateCredentials(AuthenticatableInterface $user, array $credentials): bool
    {
        if (! isset($user->id) || ! $user->id) {
            throw new BusinessException(ErrorCode::AUTH_ERROR, '账号错误');
        }

        if (!password_verify($credentials['password'], $user->getAuthPassword())) {
            throw new BusinessException(ErrorCode::AUTH_ERROR, '密码错误');
        }

        if (!$user->status) {
            throw new BusinessException(ErrorCode::AUTH_ERROR, '账号状态异常');
        }

        $info = [
            'id' => $user->id,
            'last_login_time' => date('Y-m-d H:i:s'),
            'last_login_ip' => get_real_ip(request())
        ];
        $eventDispatcher = make(EventDispatcherInterface::class);
        $eventDispatcher->dispatch(new UserLoginEvent($info, 'admin'));
        
        return true;
    }
}
